11.2.5 服务发现

作为核心网络架构,Libnetwork还提供了一些重要的网络服务。

服务发现 (Service Discovery) 允许容器和Swarm服务通过名称互相定位。唯一的要求就是需要处于同一个网络当中。

其底层实现是利用了Docker内置的DNS服务器,为每个容器提供DNS解析功能。图11.19展示了容器“c1”通过名称ping容器“c2”的过程。Swarm服务原理相同。

72.png

图11.19 容器“c1”通过名称ping容器“c2”

下面逐步分析整个过程。

(1) ping c2 命令调用本地DNS解析器,尝试将“c2”解析为具体IP地址。每个Docker容器都有本地DNS解析器。

(2)如果本地解析器在本地缓存中没有找到“c2”对应的IP地址,本地解析器会向Docker DNS服务器发起一个递归查询。本地服务解析器是预先配置好并知道Docker DNS服务器细节的。

(3)Docker DNS服务器记录了全部容器名称和IP地址的映射关系,其中容器名称是容器在创建时通过 --name 或者 --net-alias 参数设置的。这意味着Docker DNS服务器知道容器“c2”的IP地址。

(4)DNS服务返回“c2”对应的IP地址到“c1”本地DNS解析器。之所以会这样是因为两个容器位于相同的网络当中,如果所处网络不同则该命令不可行。

(5)ping命令被发往“c2”对应的IP地址。

每个启动时使用了 --name 参数的Swarm服务或者独立的容器,都会将自己的名称和IP地址注册到Docker DNS服务。这意味着容器和服务副本可以通过Docker DNS服务互相发现。

但是,服务发现是受网络限制的。这意味着名称解析只对位于同一网络中的容器和服务生效。如果两个容器在不同的网络,那么就不能互相解析。

关于服务发现和名称解析最后要说一点。

用户可以为Swarm服务和独立容器进行自定义的DNS配置。举个例子, --dns 参数允许读者指定自定义的DNS服务列表,以防出现内置的Docker DNS服务器解析失败的情况。此外也可以使用 --dns-search 参数指定自定义查询时所使用的域名(例如当查询名称并非完整域名的时候)。

在Linux上,上述工作都是通过在容器内部 /etc/resolve.conf 文件内部增加条目来实现的。

下面的例子会启动一个新的容器,并添加声名狼藉的 8.8.8.8 Google DNS服务器,同时指定 dockercents.com 作为域名添加到非完整查询当中。

$ docker container run -it --name c1 \
  --dns=8.8.8.8 \
  --dns-search=dockercerts.com \
  alpine sh

results matching ""

    No results matching ""